package de.tum.in.elitese.wahlsys.controller.beans;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import de.tum.in.elitese.wahlsys.common.data.RegionalInformation;
import de.tum.in.elitese.wahlsys.common.data.UserCredentials;

/**
 * Bean for collecting and managing the voting booths. It keeps a list of all
 * current voting booths and manages the assignment of voters to them
 * 
 * @author christoph
 */
public class VotingBoothsBean {

	private Map<String, Map<UserCredentials, RegionalInformation>> fBoothsPerNamePerOfficeMap;

	/**
	 * The constructor.
	 */
	public VotingBoothsBean() {
		super();

		fBoothsPerNamePerOfficeMap = new HashMap<String, Map<UserCredentials, RegionalInformation>>();
	}

	/**
	 * Registers a new voting booth with the given crentials to the bean
	 * 
	 * @param votingBoothCredentials
	 *            the credentials of the booth
	 */
	public void addVotingBooth(UserCredentials votingBoothCredentials) {
		// get booths
		Map<UserCredentials, RegionalInformation> booths = fBoothsPerNamePerOfficeMap.get(votingBoothCredentials.getRegionId());
		if (booths == null) {
			// no booths yet
			booths = new HashMap<UserCredentials, RegionalInformation>();
			fBoothsPerNamePerOfficeMap.put(votingBoothCredentials.getRegionId(), booths);
		}

		// add booth
		booths.put(votingBoothCredentials, null);
	}

	/**
	 * Queries the current assignment for the given voting booth
	 * 
	 * @param votingBoothCredentials
	 *            the credentials of the voting booth
	 * @return the assigned regional information, or empty if there are non
	 */
	public RegionalInformation getAssignedRegionalInformation(UserCredentials votingBoothCredentials) {
		Map<UserCredentials, RegionalInformation> booths = fBoothsPerNamePerOfficeMap.get(votingBoothCredentials.getRegionId());
		if (booths == null) {
			// no booth yet
			return null;
		}

		return booths.get(votingBoothCredentials);
	}

	/**
	 * Finds an empty voting booth for the given credentials of the election
	 * staff (finds a booth in the same office)
	 * 
	 * @param votingBoothCredentials
	 * @return the credentials of the empty booth, or null if non is empty
	 */
	public UserCredentials getEmptyVotingBooth(UserCredentials electionStaffCredentials) {
		Map<UserCredentials, RegionalInformation> booths = fBoothsPerNamePerOfficeMap.get(electionStaffCredentials.getRegionId());
		if (booths != null) {
			for (Entry<UserCredentials, RegionalInformation> entry : booths.entrySet()) {
				if (entry.getValue() == null) {
					// found free one
					return entry.getKey();
				}
			}
		}

		return null;
	}

	/**
	 * Occupies a voting booth for the voter.
	 * 
	 * @param votingBoothCredentials
	 *            the credentials of the free booth
	 * @param assignedInfo
	 *            the regional information of the voter
	 * @return true if everything worked fine
	 */
	public boolean setAssignedInfo(UserCredentials votingBoothCredentials, RegionalInformation assignedInfo) {
		Map<UserCredentials, RegionalInformation> booths = fBoothsPerNamePerOfficeMap.get(votingBoothCredentials.getRegionId());
		if (booths != null && booths.containsKey(votingBoothCredentials)) {
			booths.put(votingBoothCredentials, assignedInfo);
			return true;
		}
		return false;
	}
}
